import { message, Upload, UploadFile, UploadProps } from 'antd';
import React, { useEffect, useState } from 'react';
import { ProFormUploadButton, ProFormUploadButtonProps } from '@ant-design/pro-components';
import { MENU_CODES, MODULES, PROJECT_NAME } from '@/options';
import { getTokenHeader } from '@/requestErrorConfig';
import { msgApi, StrUtil } from '@/util/msg';

type FileTypes =
  | 'png'
  | 'jpg'
  | 'jpeg'
  | 'gif'
  | 'webp'
  | 'svg'
  | 'bmp'
  | 'mp4'
  | 'mp3'
  | 'wav'
  | 'flv'
  | 'avi'
  | 'mov'
  | 'mkv'
  | 'webm'
  | 'pdf'
  | 'doc'
  | 'docx'
  | 'xls'
  | 'xlsx'
  | 'ppt'
  | 'pptx'
  | 'txt';
const imageType: FileTypes[] = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'bmp'];
const ApiUrl = `${PROJECT_NAME}/${MODULES.MICRO}/${MENU_CODES.OSS}/file`;

export interface ProUploadRef {
  fileUrlList: string[];
  changeFileList: (newFileList: UploadFile[]) => void;
}

/**
 * 根据文件名获取uid
 * @param {string} str
 * @returns {string}
 */
const getUid = (str: string) => {
  const list = str.split(StrUtil.SLASH);
  return list[list.length - 1].split(StrUtil.DOT)[0];
};

/**
 * 根据后台返回字符串获取文件列表
 * @param {string} str
 * @returns {UploadFile<any>[]}
 */
export const getPhotoList = (str: string = '') => {
  return str.split(StrUtil.COMMIT).map((item) => {
    const uid = getUid(item);
    return {
      url: item,
      thumbUrl: item,
      uid,
      name: uid,
      status: 'done',
    } as UploadFile;
  });
};
type FileType = FileTypes[] | 'image';
type MyProTableProps = {
  initList?: UploadFile[];
  fileType?: FileType;
  multiple?: boolean;
} & ProFormUploadButtonProps;

const MyUpload: React.FC<MyProTableProps> = ({
  label = '头像',
  title = '',
  listType = 'picture-card',
  initList = [],
  fileType,
  max = 1,
  multiple = false,
  fieldProps,
  name = 'avatar',
  ...restProps
}) => {
  const [fileList, setFileList] = useState<UploadFile[]>(initList);
  const [fileUrlList, setFileUrlList] = useState<string[]>([]);
  let str = '';
  const [fileTypes, setFileTypes] = useState<FileTypes[]>();
  const [accept, setAccept] = useState<string>();

  /**
   * 更新文件列表
   * @param {UploadFile[]} newFileList
   */
  const changeFileList = (newFileList: UploadFile[]) => {
    setFileList(newFileList);
    const list = newFileList.map((item) => item.url as string);
    setFileUrlList(list);
    return list;
  };

  const onPreview = async (file: UploadFile) => {
    let src = file.url as string;
    if (fileType === 'image') {
      if (!src) {
        src = await new Promise((resolve) => {
          const reader = new FileReader();
          reader.readAsDataURL(file.originFileObj as Blob);
          reader.onload = () => resolve(reader.result as string);
        });
      }
      const image = new Image();
      image.src = src;
      const imgWindow = window.open(src);
      imgWindow?.document.write(image.outerHTML);
    } else {
      msgApi.warning('暂不支持非图片预览');
    }
  };
  const onChange: UploadProps['onChange'] = (info) => {
    let newFileList = [...info.fileList];
    let ret = info.file?.response;
    // console.log('info=======', info);
    if (info.file.status === 'error' || (info.file.status === 'done' && ret?.code !== 200)) {
      msgApi.error(ret?.message || ret?.error || '上传失败!请稍后再试');
    }
    newFileList.forEach((file) => {
      if (file.response) {
        file.url = file.response.data;
      }
    });
    // console.log(newFileList)
    changeFileList(newFileList);
  };

  const beforeUpload: UploadProps['beforeUpload'] = (file) => {
    let is = true;
    if (fileTypes && fileTypes?.length > 0) {
      const type = file.type.split('/')[1];
      is = fileTypes.includes(type as FileTypes);
    }
    if (fileTypes && !is) message.error(`${file.name} 不是 ${fileTypes.join(', ')} 格式文件`);
    return is || Upload.LIST_IGNORE;
  };

  const onRemove: UploadProps['onRemove'] = (file) => {
    const newFileList = fileList.filter((c) => c !== file);
    changeFileList(newFileList);
  };

  const props: UploadProps = {
    ...fieldProps,
    multiple,
    onPreview,
    onRemove,
    beforeUpload,
    onChange,
    headers: getTokenHeader(),
    action: ApiUrl,
  };

  useEffect(() => {
    if (str && str !== '') changeFileList(getPhotoList(str));
    if (fileType) {
      if (fileType === 'image') {
        setFileTypes(imageType);
        setAccept(imageType?.map((c) => `.${c}`).join(','));
      } else {
        setAccept(fileType?.map((c) => `.${c}`).join(','));
      }
    }
    return () => {
      changeFileList([]);
    };
  }, []);

  return (
    <ProFormUploadButton
      transform={() => fileUrlList.join(StrUtil.COMMIT) || ''}
      convertValue={(value) => {
        if (!str) str = value;
        return value;
      }}
      label={label}
      listType={listType}
      title={title || '上传' + label}
      name={name}
      max={max}
      fieldProps={props}
      fileList={fileList}
      accept={accept}
      {...restProps}
    />
  );
};

export default MyUpload;
